ACM/ICPC 之 网络流入门-EK算法(参考模板)(POJ1273)

  基于残留网络与FF算法的改进-EK算法,核心是将一条边的单向残留容量的减少看做反向残留流量的增加。

 

//网络流
//EK算法
//Time:16Ms		Memory:348K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

#define MAX 205
#define INF 0x3f3f3f3f

int n, m;
int res[MAX][MAX];
int pre[MAX];
bool v[MAX];

bool bfs(int s,int t)	//寻找s->t的增广路
{
	memset(v, false , sizeof(v));
	memset(pre, -1, sizeof(pre));
	queue<int> q;
	q.push(s);
	v[s] = true;
	while (!q.empty()) {
		int cur = q.front();	q.pop();
		for (int i = 1; i <= n; i++)
		{
			if (!v[i] && res[cur][i])
			{
				pre[i] = cur;
				if (i == t)	return true;	//找到增广路
				q.push(i);	v[i] = true;
			}
		}
	}
	return false;
}

int EK(int s, int t)
{
	int maxFlow = 0;
	while (bfs(s, t))
	{
		int mind = INF;	//最小可改进量
		for (int i = t; i != s; i = pre[i])
			mind = min(mind, res[pre[i]][i]);
		for (int i = t; i != s; i = pre[i])
		{
			res[pre[i]][i] -= mind;
			res[i][pre[i]] += mind;
		}
		maxFlow += mind;
	}
	return maxFlow;
}

int main()
{
	//freopen("in.txt", "r", stdin);

	while (~scanf("%d%d", &m, &n))
	{
		memset(res, 0, sizeof(res));
		int u, v, c;
		for (int i = 0; i < m; i++)
		{
			scanf("%d%d%d", &u, &v, &c);
			res[u][v] += c;
		}

		printf("%d\n", EK(1, n));
	}

	return 0;
}

 

posted @ 2016-07-25 16:50  文字失效  阅读(302)  评论(0编辑  收藏  举报